package actionbean;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.NoSuchElementException;

import net.sourceforge.stripes.action.ActionBean;
import net.sourceforge.stripes.action.ActionBeanContext;
import net.sourceforge.stripes.action.SimpleMessage;
import net.sourceforge.stripes.validation.SimpleError;
import net.sourceforge.stripes.validation.ValidationErrors;
import controller.BidCtrl;
import controller.CartCtrl;
import controller.RoundCtrl;
import controller.StudentCtrl;
import entity.Bid;
import entity.Course;
import entity.Round;
import entity.Section;
import entity.Student;
import exception.InputValidationErrors;

public abstract class BaseActionBean implements ActionBean {

	public static final String STUDENT_PREFIX = "/student/";
	public static final String VIEW_FOR_TIMETABLE = STUDENT_PREFIX
			+ "timetable.jsp";
	public static final String VIEW_FOR_EXAM_TIMETABLE = STUDENT_PREFIX
			+ "timetable-exam.jsp";
	public static final String URI_FOR_STUDENT_LOGIN = "/login.jsp";
	public static final String URI_FOR_LOGOUT = "/logout.jsp";
	public static final String VIEW_FOR_COURSES = STUDENT_PREFIX
			+ "courses.jsp";
	public static final String VIEW_FOR_BIDS = STUDENT_PREFIX + "bids.jsp";
	public static final String URI_FOR_COURSES = "/courses/";
	public static final String URI_FOR_TIMETABLE = "/timetable/";
	public static final String URI_FOR_BOOKMARKS = "/cart/";
	public static final String URI_FOR_BIDS = "/bids/";
	public static final String WEBSERVICE_PREFIX = "/admin-3a6a4a8a/";
	public static final String URI_FOR_ADMIN_HOMEPAGE = WEBSERVICE_PREFIX
			+ "homepage";
	public static final String URI_FOR_ADMIN_LOGIN = "/login.jsp";
	public static final String DEFAULT_STUDENT_URI = URI_FOR_COURSES;
	public static final String DEFAULT_ADMIN_URI = URI_FOR_ADMIN_HOMEPAGE;

	private ActionBeanContext context;

	private String sourcePath;

	private StudentCtrl studentCtrl = new StudentCtrl();
	private RoundCtrl roundCtrl = new RoundCtrl();
	private BidCtrl bidCtrl = new BidCtrl();
	private CartCtrl cartCtrl = new CartCtrl();

	@Override
	public ActionBeanContext getContext() {
		return context;
	}

	@Override
	public void setContext(ActionBeanContext context) {
		this.context = context;
	}

	public String getSourcePath() {
		return sourcePath;
	}

	public void setSourcePath(String sourcePath) {
		if (!sourcePath.isEmpty() && sourcePath.charAt(0) != '/') {
			sourcePath = '/' + sourcePath;
		}
		this.sourcePath = sourcePath;
	}

	public String getLoggedInUserId() {
		return (String) getContext().getRequest().getSession()
				.getAttribute("loggedInUserId");
	}

	public Student getLoggedInStudent() {
		try {
			return studentCtrl.retrieveStudentForUserId(getLoggedInUserId());
		} catch (NoSuchElementException e) {
			return null;
		}
	}

	public ArrayList<Course> retrieveCompletedCoursesForLoggedInStudent() {
		return studentCtrl
				.retrieveCompletedCoursesForStudent(getLoggedInUserId());
	}

	public Round getCurrentRound() {
		return roundCtrl.getCurrentRound();
	}

	public boolean isCurrentRoundOpen() {
		return roundCtrl.isCurrentRoundOpen();
	}

	public boolean isCurrentRoundNo(int roundNo) {
		return roundCtrl.isCurrentRoundNo(roundNo);
	}

	public String getCurrentRoundDescription() {
		if (!isCurrentRoundOpen()) {
			return "Please wait for next round opening.";
		} else if (isCurrentRoundNo(Round.ROUND_ONE)) {
			return "You can only bid for own school courses.";
		} else {
			return "You can bid for any school courses.";
		}
	}

	public String pathToResource(String uri) {
		return getContext().getServletContext().getContextPath() + uri;
	}

	public double toTwoDecimalPlaces(double number) {
		DecimalFormat decimalFormat = new DecimalFormat("0.00");
		String numberToTwoDp = decimalFormat.format(number);
		return Double.valueOf(numberToTwoDp);
	}

	protected ArrayList<Section> getPendingSectionsForLoggedInStudent(
			ArrayList<Bid> pendingBidsForLoggedInStudent) {
		ArrayList<Section> pendingSections = new ArrayList<Section>();
		for (Bid eachPendingBid : pendingBidsForLoggedInStudent) {
			pendingSections.add(eachPendingBid.getSection());
		}
		return pendingSections;
	}

	protected ArrayList<Section> retrieveBookmarkedSectionsForLoggedInStudent() {
		return cartCtrl.retrieveSectionsForStudent(getLoggedInUserId());
	}

	protected ArrayList<Bid> retrieveAllBidsForLoggedInStudent() {
		return bidCtrl.retrieveAllBidsForStudent(getLoggedInUserId());
	}

	protected void addFeedbackMessage(SimpleMessage message) {
		getContext().getMessages().add(message);
	}

	protected void addFieldError(String field, String message) {
		getContext().getValidationErrors().add(field, new SimpleError(message));
	}

	protected void setGlobalValidationError(SimpleError error) {
		ValidationErrors errors = new ValidationErrors();
		errors.addGlobalError(error);
		getContext().setValidationErrors(errors);
	}

	protected void setGlobalValidationError(InputValidationErrors e) {
		ValidationErrors errors = new ValidationErrors();
		for (Object msg : e.toJsonArray().toArray()) {
			errors.addGlobalError(new SimpleError(msg.toString()));
		}
		getContext().setValidationErrors(errors);
	}

}
